// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: taekwon

#pragma once

#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>

#include "coin/proto/coin_order_gateway.pb.h"
#include "coin2/app/driver.h"
#include "coin2/exchange/base/feed/subscriber.h"
#include "coin2/exchange/base/order/order.h"
#include "coin2/strategy/config_service.grpc.pb.h"
#include "coin2/strategy/order_executor.pb.h"
#include "coin2/strategy/order_executor/executor.h"
#include "coin2/strategy/util/reporter.h"
#include "coin2/strategy/util/reporter2.h"

namespace coin2::strategy {

using coin2::exchange::base::symbology::IProduct;
using coin2::strategy::util::StrategyReporter;
using coin2::strategy::util::StrategyReporter2;
using order_executor::OrderExecutorSystem;
using coin2::exchange::base::feed::timer::FeedTimer;

// You can use IStrategy for 'no-op' strategy
class IStrategy : public exchange::base::feed::IFeedSubscriber,
                  public exchange::base::order::IOrderSubscriber {
 public:
  virtual ~IStrategy() = default;

  virtual void UpdateDriverConfig(coin2::app::DriverConfig* config) {}
  virtual void Init(::coin2::app::Driver* driver) {}
  virtual void onCleanup(::coin2::app::Driver* driver) {}

  void onTradeFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onBookFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onLiquidationFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onOpenInterestFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onMarkPriceFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onIndexFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onFundingRateFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onIvGreeksFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onNavFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onKlineFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onWalletFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onMarketAnalysisFeed(const exchange::base::feed::FeedUpdate&) override {}
  void onTopLongShortAccountRatioFeed(const exchange::base::feed::FeedUpdate& upd) {};
  void onTopLongShortPositionRatioFeed(const exchange::base::feed::FeedUpdate& upd) {};
  void onGlobalLongShortAccountRatioFeed(const exchange::base::feed::FeedUpdate& upd) {};
  void onTakerBuySellRatioFeed(const exchange::base::feed::FeedUpdate& upd) {};
  void onOpenInterestHistFeed(const exchange::base::feed::FeedUpdate& upd) {};
  void onHeartbeatFeed(const FeedTimer& timer) override {}
  void onAccountInfo(const exchange::base::order::OrderUpdate&) override {}
  void onAccountOrder(const exchange::base::order::OrderUpdate&) override {}
  void onOrderSubsystemError(const exchange::base::order::OrderUpdate&) override {}
  void onOrderLog(const coin::proto::OrderGatewayLog&) override {}

  virtual void onInternalControlRequest(const coin2::strategy::util::InternalControlRequest&) {}
};

}  // namespace coin2::strategy
